package com.zhaiweijia.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

public class DateUtil {
	/**
	 * 功能：根据前一个日期和后一个日期计算之间的值
	 * 示例：前一个日期是2000-10-10， 后一个时间是2009-10-02
	 * @param preDay 前一个时间
	 * @param nextDay后一个时间
	 * @return
	 */
	public static int getAge(Date preDay,Date nextDay) {
		//TODO 实现代码
		//2000 10 20   19 
		//2000 10 19   20    
		// 获取出生的年、月  日
		int bYear = preDay.getYear();
		int bMhonth = preDay.getMonth();
		int bDate = preDay.getDate();

		// 获取今天的年月日
		
		int tYear = nextDay.getYear();
		int tMhonth = nextDay.getMonth();
		int tDate = nextDay.getDate();

		int age = tYear - bYear;

		// 年龄算大了
		if (tMhonth < bMhonth)
			age--;

		if (tMhonth == bMhonth && tDate < bDate)
			age--;

		return age;
	}

	/**
	 * 功能：根据生日计算年龄 示例：现在是2020-4-23，如果生日是2020-5-20，那结果是19
	 * 
	 * @param Date，生日
	 * @return int 年龄
	 */
	public static int getAge(Date birthday) {
		//使用当前年份， 减去生日的年份
		Calendar calendar = Calendar.getInstance();

		//获取当前日期的年月日
		//当前的年份
		int now_year = calendar.get(Calendar.YEAR);
		//当前的月份
		int now_month = calendar.get(Calendar.MONTH);
		//当前的日期
		int now_day = calendar.get(Calendar.DAY_OF_MONTH);

		//获取生日的年月日
		calendar.setTime(birthday);

		//生日的年份
		int birth_year = calendar.get(Calendar.YEAR);
		//生日的月份
		int birth_month = calendar.get(Calendar.MONTH);
		//生日的日期
		int birth_day = calendar.get(Calendar.DAY_OF_MONTH);

		//计算年龄
		int age = now_year - birth_year;

		//如果当前月份小于生日的月份，则年龄减一
		if (now_month < birth_month) {
			age--;

			//如果同月份，但是日期还不到，则年龄减一
		} else if (now_month == birth_month && now_day < birth_day) {
			age--;
		}

		return age;
	}

	/**
	 * 功能：将Date类型的日期转换成String类型
	 * 
	 * @param Date，日期
	 * @return String类型的日期
	 */
	public static String getStringFromDate(Date date) {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		return sdf.format(date);
	}

	/**
	 * 功能：将Date类型的日期转换成String类型
	 * 
	 * @param String，日期
	 * @return Date 类型的日期
	 * @throws ParseException
	 */
	public static Date getDateFromString(String date) throws ParseException {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		return sdf.parse(date);
	}

	/**
	 * 功能：将Date类型的日期转换成String类型
	 * 
	 * @param Date，日期
	 * @param String  pattern，日期格式
	 * @return String类型的日期
	 */
	public static String getStringFromDate(Date date, String pattern) {

		SimpleDateFormat sdf = new SimpleDateFormat(pattern);

		return sdf.format(date);
	}

	/**
	 * 功能：将Date类型的日期转换成String类型
	 * 
	 * @param String，日期
	 * @param String    pattern，日期格式
	 * @return Date 类型的日期
	 * @throws ParseException
	 */
	public static Date getDateFromString(String date, String pattern) throws ParseException {

		SimpleDateFormat sdf = new SimpleDateFormat(pattern);

		return sdf.parse(date);
	}

	/**
	 * 功能：给定时间对象，获取该时间的月初1日0时0分0秒0毫秒 示例：2018-11-11 08:30:16 → 2018-11-01 00:00:00
	 * 使用场景：可用在数据库里查询某月的时间范围
	 *
	 * @param Date 源时间
	 * @return Date 月初时间
	 */
	public static Date getFirstDayOfMonth(Date src) {

		//获取日历对象
		Calendar calendar = Calendar.getInstance();

		//设置指定日期
		calendar.setTime(src);

		//设置日期为1号
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		//设置时分秒分别为0
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);

		return calendar.getTime();
	}

	/**
	 * 功能：给定时间对象，获取该时间的月末最后一天的23时23分59秒999毫秒 示例：2018-11-11 08:30:16 → 2018-11-30
	 * 23:23:59 使用场景：可用在数据库里查询某月的时间范围
	 *
	 * @param Date 源时间
	 * @return Date 月末时间
	 */
	public static Date getLastDayOfMonth(Date src) {
		//获取当前月的第一天
		Date firstDayOfMonth = getFirstDayOfMonth(src);

		//创建日历对象
		Calendar calendar = Calendar.getInstance();

		//设置时间
		calendar.setTime(firstDayOfMonth);

		//让月份+1
		calendar.add(Calendar.MONTH, 1);

		//让毫秒值-1
		calendar.add(Calendar.MILLISECOND, -1);

		return calendar.getTime();
	}

	/**
	 * 功能：获取当前日期指定天数之前或之后的日期，如果参数为负数，则往前回滚。 示例1：当前是2018-08-08，参数days=5，结果是2018-08-13
	 * 示例2：当前是2018-08-08，参数days=-4，结果是2018-08-04
	 * 
	 * @param int days 偏移的天数，如果为负数则往前回滚。
	 * @return Date 新日期
	 */
	public static Date offsetDate(int days) {
		//创建日历对象
		Calendar calendar = Calendar.getInstance();

		//让月份+1
		calendar.add(Calendar.DAY_OF_MONTH, days);

		return calendar.getTime();
	}

	/**
	 * 功能：获取当前季节，如春季、夏季、秋季、冬季。
	 * 
	 * @return Season 季节
	 */
	public static Season getCurrentSeason() {

		//获取日历对象
		Calendar calendar = Calendar.getInstance();

		//获取月份，因为是从0开始，所以需要+1
		int month = calendar.get(Calendar.MONTH) + 1;

		if (month >= 3 && month <= 5) {
			return Season.春;

		} else if (month >= 6 && month <= 8) {

			return Season.夏;
		} else if (month >= 9 && month <= 11) {

			return Season.秋;
		} else {

			return Season.冬;
		}

	}

	/**
	 * 功能：获取人性化时间，例如5分钟之内则显示“刚刚”，其它显示16分钟前、2小时前、3天前、4月前、5年前等
	 *
	 * @param Date date 源时间。
	 * @return 人性化时间
	 */
	public static String getDisplayTime(Date date) {

		//根据毫秒值进行计算
		Date now = new Date();

		//获取当前时间的毫秒值
		long now_time = now.getTime();

		//获取指定日期的毫秒值
		long time = date.getTime();

		//获取时间差，单位为毫秒值
		long cha = now_time - time;

		//将毫秒值转换成时分秒年月日

		if (cha / 1000 / 60 < 5) {
			return "刚刚";
		} else if (cha / 1000 / 60 < 60) {

			return (cha / 1000 / 60) + "分钟前";

		} else if (cha / 1000 / 60 / 60 < 24) {

			return (cha / 1000 / 60 / 60) + "小时前";

		} else if (cha / 1000 / 60 / 60 / 24 < 30) {

			return (cha / 1000 / 60 / 60 / 24) + "天前";

		} else if (cha / 1000 / 60 / 60 / 24 / 30 < 12) {

			return (cha / 1000 / 60 / 60 / 24 / 30) + "月前";

		} else {

			return (cha / 1000 / 60 / 60 / 24 / 30 / 12) + "年前";
		}

	}

	/**
	 * 功能：获取人性化时间，例如5分钟之内则显示“刚刚”，其它显示16分钟前、2小时前、3天前、4月前、5年前等
	 *
	 * @param Date preDay 前一个时间。
	 * @param Date nextDay 后一个时间。
	 * @return 人性化时间
	 */
	public static String getDisplayTime(Date preDay,Date nextDay) {

		//根据毫秒值进行计算
		

		//获取当前时间的毫秒值
		long now_time = nextDay.getTime();

		//获取指定日期的毫秒值
		long time = preDay.getTime();

		//获取时间差，单位为毫秒值
		long cha = now_time - time;

		//将毫秒值转换成时分秒年月日

		if (cha / 1000 / 60 < 5) {
			return "刚刚";
		} else if (cha / 1000 / 60 < 60) {

			return (cha / 1000 / 60) + "分钟前";

		} else if (cha / 1000 / 60 / 60 < 24) {

			return (cha / 1000 / 60 / 60) + "小时前";

		} else if (cha / 1000 / 60 / 60 / 24 < 30) {

			return (cha / 1000 / 60 / 60 / 24) + "天前";

		} else if (cha / 1000 / 60 / 60 / 24 / 30 < 12) {

			return (cha / 1000 / 60 / 60 / 24 / 30) + "月前";

		} else {

			return (cha / 1000 / 60 / 60 / 24 / 30 / 12) + "年前";
		}

	}
	/**
	 * 功能：根据日期计算到现在的月份 示例：现在是2020-11-23，如果日期是2020-5-20，那结果是6
	 * 
	 * @param Date，日期
	 * @return int 月份数量
	 */
	public static int getMonths(Date date) {
		//使用当前年份， 减去日期的年份
		Calendar calendar = Calendar.getInstance();

		//获取当前日期的年月日
		//当前的年份
		int now_year = calendar.get(Calendar.YEAR);
		//当前的月份
		int now_month = calendar.get(Calendar.MONTH);
		//当前的日期
		int now_day = calendar.get(Calendar.DAY_OF_MONTH);

		//获取日期的年月日
		calendar.setTime(date);

		//日期的年份
		int date_year = calendar.get(Calendar.YEAR);
		//日期的月份
		int date_month = calendar.get(Calendar.MONTH);
		//日期的日期
		int date_day = calendar.get(Calendar.DAY_OF_MONTH);

		//计算年数
		int year = now_year - date_year;

		//年数乘以12，然后加上现在月份和指定月份的差
		int months = year * 12 + (now_month - date_month);

		//如果日期不到，则月份减1
		if (now_day < date_day) {
			months--;
		}

		return months;
	}
}
